package com.example.service;

import cn.hutool.core.util.ObjectUtil;
import com.example.common.enums.ResultCodeEnum;
import com.example.common.enums.RoleEnum;
import com.example.entity.*;
import com.example.exception.CustomException;
import com.example.mapper.AdminMapper;
import com.example.mapper.DoctorMapper;
import com.example.mapper.PatientsMapper;
import com.example.mapper.PharmacistMapper;
import com.example.utils.BcryptUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;

@Service
public class UpdatePasswordService {

    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private PatientsMapper patientsMapper;
    @Autowired
    private DoctorMapper doctorMapper;
    @Autowired
    private PharmacistMapper pharmacistMapper;

    public void updatePassword(Account account) {
        switch (account.getRole()) {
            case "ADMIN":
                updatePasswordCommon(account,
                        adminMapper::selectById,
                        adminMapper::updateById,
                        Admin::getPassword,
                        Admin::setPassword);
                break;
            case "DOCTOR":
                updatePasswordCommon(account,
                        doctorMapper::selectById,
                        doctorMapper::updateById,
                        Doctor::getPassword,
                        Doctor::setPassword);
                break;
            case "PATIENT":
                updatePasswordCommon(account,
                        patientsMapper::selectById,
                        patientsMapper::updateById,
                        Patients::getPassword,
                        Patients::setPassword);
                break;
            case "PHARMACIST":
                updatePasswordCommon(account,
                        pharmacistMapper::selectById,
                        pharmacistMapper::updateById,
                        Pharmacist::getPassword,
                        Pharmacist::setPassword);
                break;
            default:
                throw new CustomException(ResultCodeEnum.INVALID_ROLE);
        }
    }

    private <T> void updatePasswordCommon(Account account,
                                          Function<Integer, T> selectById,
                                          Consumer<T> updateById,
                                          Function<T, String> getPassword,
                                          BiConsumer<T, String> setPassword) {
        // 查询用户
        T dbUser = selectById.apply(account.getId());
        if (dbUser == null) {
            throw new CustomException(ResultCodeEnum.USER_NOT_EXIST);
        }

        // 校验旧密码
        if (!BcryptUtil.match(account.getPassword(), getPassword.apply(dbUser))) {// 旧密码与数据库密码匹配判断
            throw new CustomException(ResultCodeEnum.PARAM_PASSWORD_ERROR);
        }

        // 更新新密码
        String newEncodePassword = BcryptUtil.encode(account.getNewPassword());
        setPassword.accept(dbUser, newEncodePassword);
        updateById.accept(dbUser);
    }
}
